/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.components.tables.creator;
import java.util.AbstractMap.SimpleEntry;
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import com.opendoorlogistics.api.tables.ODLColumnType;
import com.opendoorlogistics.api.tables.ODLTableDefinitionAlterable;
import com.opendoorlogistics.api.tables.TableFlags;
import com.opendoorlogistics.core.tables.utils.DatastoreCopier;
import com.opendoorlogistics.core.tables.utils.TableUtils;
import com.opendoorlogistics.core.utils.strings.Strings;
import com.opendoorlogistics.utils.ui.tables.AbstractTableDefinitionGrid;
public class TableDefinitionGrid extends AbstractTableDefinitionGrid {
private ODLTableDefinitionAlterable dfn;
private final boolean showFlags;
public TableDefinitionGrid(ODLTableDefinitionAlterable dfn, boolean showFlags) {
this.showFlags = showFlags;
setTable(dfn);
updateAppearance();
}
public void setTable(ODLTableDefinitionAlterable dfn) {
this.dfn = dfn;
table.setModel(new MyTableModel());
// create jcombobox for enum
JComboBox<ODLColumnType> combo = new JComboBox<>(ODLColumnType.standardTypes());
TableColumn column = table.getColumnModel().getColumn(1);
column.setCellEditor(new DefaultCellEditor(combo));
for(int i =0 ; i< 2 ; i++){
table.getColumnModel().getColumn(i).setCellRenderer(new DefaultTableCellRenderer(){
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component ret = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// read-only in italics
if(row < dfn.getColumnCount()){
if((dfn.getColumnFlags(row) & TableFlags.FLAG_LINKED_EXCEL_READ_ONLY_DATA)==TableFlags.FLAG_LINKED_EXCEL_READ_ONLY_DATA){
ret.setFont(ret.getFont().deriveFont(Font.ITALIC));
}
}
return ret;
}
});
}
}
private class MyTableModel extends AbstractTableModel {
private final ArrayList<SimpleEntry<String, Long>> flags = new ArrayList<>();
private final int nbNonFlagFields = 2;
public MyTableModel() {
flags.add(new SimpleEntry<>("Optional", TableFlags.FLAG_IS_OPTIONAL));
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Column name";
case 1:
return "Type";
}
return flags.get(column - nbNonFlagFields).getKey();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return isNonLinkedCol(rowIndex);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return ODLColumnType.class;
}
return Boolean.class;
}
@Override
public int getRowCount() {
return dfn.getColumnCount();
}
@Override
public int getColumnCount() {
return nbNonFlagFields + (showFlags? flags.size():0);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return dfn.getColumnName(rowIndex);
case 1:
return dfn.getColumnType(rowIndex);
}
long flags = dfn.getColumnFlags(rowIndex);
long flag = this.flags.get(columnIndex - nbNonFlagFields).getValue();
boolean isOn = (flags & flag)!=0;
return isOn;
}
@Override
public void setValueAt(Object aValue, final int rowIndex, int columnIndex) {
String name = dfn.getColumnName(rowIndex);
ODLColumnType type = dfn.getColumnType(rowIndex);
long flags = dfn.getFlags();
switch (columnIndex) {
case 0:
name = (String) aValue;
if (name == null) {
name = "";
}
break;
case 1:
type = (ODLColumnType) aValue;
if (type == null) {
type = ODLColumnType.STRING;
}
break;
}
if (columnIndex >= nbNonFlagFields) {
long flag = this.flags.get(columnIndex - nbNonFlagFields).getValue();
Boolean b = (Boolean) aValue;
if (b) {
flags |= flag;
} else {
flags &= ~flag;
}
}
if(type == dfn.getColumnType(rowIndex) && flags == dfn.getColumnFlags(rowIndex) && Strings.equals(name, dfn.getColumnName(rowIndex))){
// nothing to modify so don't start the transaction as it will fire listeners
return;
}
final long finalFlags = flags;
final String finalName = name;
final ODLColumnType finalType = type;
modify(new Runnable() {
public void run() {
DatastoreCopier.modifyColumnWithoutTransaction(rowIndex, rowIndex, finalName, finalType, finalFlags, dfn);
}
});
}
}
@Override
protected void createNewColumn() {
modify(new Runnable() {
@Override
public void run() {
String name = TableUtils.getUniqueNumberedColumnName("New column", dfn);
dfn.addColumn(-1,name, ODLColumnType.STRING, 0);
}
});
setTable(dfn);
}
@Override
protected void moveItemUp(final int row) {
modify(new Runnable() {
@Override
public void run() {
DatastoreCopier.modifyColumnWithoutTransaction(row, row-1, dfn.getColumnName(row), dfn.getColumnType(row), dfn.getColumnFlags(row), dfn);
}
});
setTable(dfn);
}
@Override
protected void moveItemDown(final int row) {
modify(new Runnable() {
@Override
public void run() {
DatastoreCopier.modifyColumnWithoutTransaction(row, row+1, dfn.getColumnName(row), dfn.getColumnType(row), dfn.getColumnFlags(row), dfn);
}
});
setTable(dfn);
}
@Override
protected void deleteItem(final int row) {
modify(new Runnable() {
@Override
public void run() {
dfn.deleteColumn(row);
}
});
setTable(dfn);
updateAppearance();
}
protected void modify(Runnable runnable){
runnable.run();
}
@Override
protected boolean isDeleteColumnAllowed(int col){
return isNonLinkedCol(col);
}
private boolean isNonLinkedCol(int col) {
if(col < dfn.getColumnCount()){
return (dfn.getColumnFlags(col) & TableFlags.FLAG_LINKED_EXCEL_READ_ONLY_DATA)!=TableFlags.FLAG_LINKED_EXCEL_READ_ONLY_DATA;
}
return true;
}
}